/*
 * Copyright (c) 2023 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ohos_init.h"
#include "los_task.h"
#include "intelligent_agriculture.h"

#define SOIL_HUMIDITY_MIN          10           //土壤湿度干燥阈值
#define SOIL_HUMIDITY_MAX          35           //土壤湿度湿润阈值
#define LIGHT_INTENSITY_MIN        100          //光线强度暗阈值
#define LIGHT_INTENSITY_MAX        300          //光线强度亮阈值

#define LOG_IA_TAG                 "ia"
#define LOG_IA_TAG_INFO            "["LOG_IA_TAG"          %4d] "
#define LOG_IA_TAG_SOIL            "["LOG_IA_TAG" soil     %4d] "
#define LOG_IA_TAG_LIGHT           "["LOG_IA_TAG" light    %4d] "
#define LOG_IA_TAG_WATER           "["LOG_IA_TAG" water    %4d] "
#define LOG_IA_TAG_SHED            "["LOG_IA_TAG" shed     %4d] "
#define LOG_IA_TAG_LCD             "["LOG_IA_TAG" lcd      %4d] "


#define THREAD_START_INFO                                      \
{                                                              \
    int len = strlen(__FUNCTION__);                            \
    int count = (44 - len)/2;                                  \
    char temp[51] = {0};                                       \
    memset(temp, '=', count);                                  \
    memcpy(&temp[count], __FUNCTION__, len);                   \
    temp[strlen(temp)] = ' ';                                  \
    memcpy(&temp[strlen(temp)], "start", 5);                   \
    if(len%2)temp[strlen(temp)] = ' ';                         \
    memset(&temp[strlen(temp)], '=', count);                   \
    printf(LOG_IA_TAG_INFO"%s\r\n", __LINE__, temp);           \
}

ia_example_t g_ia_example =
{
    .dev          = &g_ia_dev,
    .work_mode    = WORK_MODE_AUTO,
};


/***************************************************************
* 函数名称: get_soil_humidity
* 说    明: 获取土壤湿度
* 参    数: ia_example_t *ia
* 返 回 值: float
***************************************************************/
static float get_soil_humidity(ia_example_t *ia)
{
    return ia->dev->soil_humidity->value;
}

/***************************************************************
* 函数名称: get_light_intensity
* 说    明: 获取光线强度
* 参    数: ia_example_t *ia
* 返 回 值: float
***************************************************************/
static float get_light_intensity(ia_example_t *ia)
{
    return ia->dev->light_intensity->value;
}

/***************************************************************
* 函数名称: get_diaplay_data
* 说    明: 获取显示数据
* 参    数: ia_example_t *ia
* 返 回 值: display_data_t
***************************************************************/
static display_data_t get_diaplay_data(ia_example_t *ia)
{
    display_data_t dd = {0};
    dd.soil_humidity    = ia->dev->soil_humidity->value;
    dd.light_intensity  = ia->dev->light_intensity->value;
    dd.water_pump_onoff = ia->dev->water_pump->onoff;
    dd.shed_cover_onoff = ia->dev->shed_cover->onoff;
    
    return dd;
}

/***************************************************************
* 函数名称: ia_soil_humidity_thread
* 说    明: 土壤湿度检测线程
* 参    数: void *args
* 返 回 值: 无
***************************************************************/
void ia_soil_humidity_thread(void *args)
{
    ia_example_t       *ia = (ia_example_t *)args;
    ia_soil_humidity_t *sh = ia->dev->soil_humidity;
    float sh_value = 0;
    
    THREAD_START_INFO
    ia_soil_humidity_init(sh);
    printf(LOG_IA_TAG_SOIL"init finish\r\n", __LINE__);
    
    while (1)
    {
        sh_value = ia_get_soil_humidity(sh);
        printf(LOG_IA_TAG_SOIL"土壤湿度:%.3f%%, %.3fV\r\n", __LINE__, sh->value, sh_value);
        while (!sh->is_continue)
        {
            LOS_Msleep(100);
        }
        LOS_Msleep(2000);
    }
}

/***************************************************************
* 函数名称: ia_light_intensity_thread
* 说    明: 光线强度检测线程
* 参    数: void *args
* 返 回 值: 无
***************************************************************/
void ia_light_intensity_thread(void *args)
{
    ia_example_t         *ia = (ia_example_t *)args;
    ia_light_intensity_t *li = ia->dev->light_intensity;
    
    THREAD_START_INFO
    ia_light_intensity_init(li);
    printf(LOG_IA_TAG_LIGHT"init finish\r\n", __LINE__);
    
    while (1)
    {
        ia_get_light_intensity(li);
        printf(LOG_IA_TAG_LIGHT"光照强度：%.3flux\r\n", __LINE__, li->value);
        while (!li->is_continue)
        {
            LOS_Msleep(100);
        }
        LOS_Msleep(1000);
    }
}

/***************************************************************
* 函数名称: ia_water_pump_thread
* 说    明: 水泵控制线程
* 参    数: void *args
* 返 回 值: 无
***************************************************************/
void ia_water_pump_thread(void *args)
{
    ia_example_t    *ia = (ia_example_t *)args;
    ia_water_pump_t *wp = ia->dev->water_pump;
    float sh_value = 0;
    
    THREAD_START_INFO
    ia_water_pump_init(wp);
    printf(LOG_IA_TAG_WATER"init finish\r\n", __LINE__);
    
    while (1)
    {
        if (ia->work_mode == WORK_MODE_AUTO)
        {
            sh_value = get_soil_humidity(ia);
            if (sh_value  > SOIL_HUMIDITY_MAX && wp->onoff == ON)
            {
                ia_set_water_pump(wp, OFF);
                printf(LOG_IA_TAG_WATER"water pump:OFF\r\n", __LINE__);
                LOS_Msleep(5000);
                continue;
            }
            
            if (sh_value < SOIL_HUMIDITY_MIN && wp->onoff == OFF)
            {
                ia_set_water_pump(wp, ON);
                printf(LOG_IA_TAG_WATER"water pump:ON\r\n", __LINE__);
            }
        }
        LOS_Msleep(500);
    }
}

/***************************************************************
* 函数名称: ia_shed_cove_thread
* 说    明: 棚罩控制线程
* 参    数: void *args
* 返 回 值: 无
***************************************************************/
void ia_shed_cove_thread(void *args)
{
    ia_example_t    *ia = (ia_example_t *)args;
    ia_shed_cover_t *sc = ia->dev->shed_cover;
    float li_value = 0;
    
    THREAD_START_INFO
    ia_shed_cover_init(sc);
    printf(LOG_IA_TAG_SHED"init finish\r\n", __LINE__);
    
    while (1)
    {
        if (ia->work_mode == WORK_MODE_AUTO)
        {
            li_value = get_light_intensity(ia);
            if (li_value  < LIGHT_INTENSITY_MIN && sc->onoff == OFF)
            {
                ia_set_shed_cover(sc, ON);
                printf(LOG_IA_TAG_SHED"shed cover:ON\r\n", __LINE__);
                LOS_Msleep(5000);
                continue;
            }
            
            if (li_value  > LIGHT_INTENSITY_MAX && sc->onoff == ON)
            {
                ia_set_shed_cover(sc, OFF);
                printf(LOG_IA_TAG_SHED"shed cover:OFF\r\n", __LINE__);
                LOS_Msleep(5000);
                continue;
            }
        }
        LOS_Msleep(1000);
    }
}

/***************************************************************
* 函数名称: ia_lcd_thread
* 说    明: lcd显示线程
* 参    数: void *args
* 返 回 值: 无
***************************************************************/
void ia_lcd_thread(void *args)
{
    ia_example_t *ia  = (ia_example_t *)args;
    ia_lcd_t     *lcd = ia->dev->lcd;
    
    THREAD_START_INFO
    ia_lcd_init(&lcd->param);
    printf(LOG_IA_TAG_LCD"init finish\r\n", __LINE__);
    ia_lcd_data_display(lcd, ia->dev);
    
    while (1)
    {
        if (!mqtt_connected())
        {
            ia_iot_thread(NULL);
        }
        ia->display_data = get_diaplay_data(ia);
        if (ia->display_data_last.soil_humidity != ia->display_data.soil_humidity)
        {
            ia_lcd_soil_humidity_display(lcd, ia->dev);
        }
        
        if (ia->display_data_last.light_intensity != ia->display_data.light_intensity)
        {
            ia_lcd_light_intensity_display(lcd, ia->dev);
        }
        
        if (ia->display_data_last.water_pump_onoff != ia->display_data.water_pump_onoff)
        {
            ia_lcd_water_pump_display(lcd, ia->dev);
        }
        
        if (ia->display_data_last.shed_cover_onoff != ia->display_data.shed_cover_onoff)
        {
            ia_lcd_shed_cover_display(lcd, ia->dev);
        }
        ia->display_data_last = ia->display_data;
        
        send_msg_to_mqtt();
        LOS_Msleep(500);
    }
}

void ia_iot_thread(void *args)
{
reconnect:
    printf("arrived here 1!!!!!!!!\r\n");
    ExternalTaskConfigNetwork();//weizhangei add
    SetWifiModeOff();
    SetApModeOff();
    printf("arrived here 2!!!!!!!!\r\n");
    SetWifiModeOn();
    printf("arrived here 3!!!!!!!!\r\n");
    mqtt_init();
    printf("arrived here 4!!!!!!!!\r\n");
    while (1)
    {
        if (!wait_message())
        {
            goto reconnect;
        } else {
            return;
        }
    }
}

/***************************************************************
* 函数名称: create_task
* 说    明: 创建任务
* 参    数: unsigned int *threadID,  uint32_t size, uint8_t prio,
*           ThreadFunc func, void *args, const char *owner
* 返 回 值: int
***************************************************************/
int create_task(unsigned int *threadID,  uint32_t size, uint8_t prio, ThreadFunc func, void *args, const char *owner)
{
    int              ret  = 0;
    TSK_INIT_PARAM_S task = {0};
    
    task.pfnTaskEntry = (TSK_ENTRY_FUNC)func;
    task.uwStackSize  = size;
    task.pcName       = (char *)owner;
    task.uwArg        = (uint32_t)args;
    task.usTaskPrio   = prio > 30 ? 30 : prio;
    ret = LOS_TaskCreate(threadID, &task);
    if (ret != LOS_OK)
    {
        LZ_HARDWARE_LOGE("create_task", "%s ret = 0x%x\n", ret == LOS_OK ? "OK" : "FAILURE", ret);
    }
    
    return (ret == LOS_OK) ? LZ_HARDWARE_SUCCESS : LZ_HARDWARE_FAILURE;
}


/***************************************************************
* 函数名称: e53_ia_example
* 说    明: 智慧农业例程
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void e53_ia_example(void)
{
    ia_example_t *ia = &g_ia_example;
    
    LOS_Msleep(1000);
    printf(LOG_IA_TAG_INFO"欢迎使用 智慧农业\r\n", __LINE__);
    
    create_task(&ia->thread_id[THREAD_ID_LCD],              10240, 15, ia_lcd_thread,             ia, "lcd");
    LOS_Msleep(10);
    create_task(&ia->thread_id[THREAD_ID_SOIL_HUMIDITY],    10240, 15, ia_soil_humidity_thread,   ia, "soil_humidity");
    LOS_Msleep(10);
    create_task(&ia->thread_id[THREAD_ID_LIGHT_INTENSITY],  10240, 15, ia_light_intensity_thread, ia, "light_intensity");
    LOS_Msleep(10);
    create_task(&ia->thread_id[THREAD_ID_WATER_PUMP],       10240, 15, ia_water_pump_thread,      ia, "water_pump");
    LOS_Msleep(10);
    create_task(&ia->thread_id[THREAD_ID_SHED_COVER],       10240, 15, ia_shed_cove_thread,       ia, "shed_cove");
    //LOS_Msleep(10);
    //create_task(&ia->thread_id[THREAD_ID_IOT],              10240, 15, ia_iot_thread,              ia, "iot_thread");
}

APP_FEATURE_INIT(e53_ia_example);
